#include "mainwindow.h"
#include "ui_mainwindow.h"

/* 参考 https://blog.csdn.net/nchu_zhangyiqing/article/details/113726446 */

void MainWindow::displaytime_setNtp()
{
    ntpIP = "time.windows.com";    //windows NTP服务器地址

    udpSocket = new QUdpSocket(this);
    connect(udpSocket,SIGNAL(connected()),this,SLOT(displaytime_connectSucess()));
    connect(udpSocket,SIGNAL(readyRead()),this,SLOT(displaytime_readingDataGrams()));
    udpSocket->connectToHost(ntpIP,123);
}

void MainWindow::displaytime_connectSucess()
{
    qDebug() << "connectSucess to ntpIP: " << ntpIP;
    qint8 LI=0;  //无预告
    qint8 VN=3;  //版本号
    qint8 MODE=3; //客户端几
    qint8 STRATUM=0;//表示本地时钟层次水平
    qint8 POLL=4; //测试间隔
    qint8 PREC=-6; //表示本地时钟精度
    QDateTime Epoch(QDate(1900, 1, 1));
    qint32 second=quint32(Epoch.secsTo(QDateTime::currentDateTime()));

    qint32 temp=0;
    QByteArray timeRequest(48, 0);
    timeRequest[0]=(LI <<6) | (VN <<3) | (MODE);
    timeRequest[1]=STRATUM;
    timeRequest[2]=POLL;
    timeRequest[3]=PREC & 0xff;
    timeRequest[5]=1;
    timeRequest[9]=1;

    //40到43字节保存原始时间戳，即客户端发送的时间
    timeRequest[40]=(temp=(second&0xff000000)>>24);
    temp=0;
    timeRequest[41]=(temp=(second&0x00ff0000)>>16);
    temp=0;
    timeRequest[42]=(temp=(second&0x0000ff00)>>8);
    temp=0;
    timeRequest[43]=((second&0x000000ff));
    udpSocket -> flush();
    udpSocket -> write(timeRequest);
    udpSocket -> flush();
}

void MainWindow::displaytime_readingDataGrams()
{
    qDebug() << "readingDataGrams to ntpIP.";
    QByteArray newTime;
    QDateTime Epoch(QDate(1900, 1, 1));
    QDateTime unixStart(QDate(1970, 1, 1));
    do
    {
        newTime.resize(udpSocket->pendingDatagramSize());
        udpSocket->read(newTime.data(), newTime.size());
    }while(udpSocket->hasPendingDatagrams());

    QByteArray TransmitTimeStamp ;
    TransmitTimeStamp=newTime.right(8);
    quint32 seconds=TransmitTimeStamp[0];
    quint8 temp=0;
    for(int j=1;j<=3;j++)
    {
        seconds=seconds<<8;
        temp=TransmitTimeStamp[j];
        seconds=seconds+temp;
    }
    dateTime.setTime_t(seconds - Epoch.secsTo(unixStart));

    this->udpSocket->disconnectFromHost();
    this->udpSocket->close();
}

void MainWindow::displaytime_getNetworkTimeCallback(QNetworkReply *reply)
{
    QJsonObject jsonObject = Http::checkHttpResponseError(reply);
    if(jsonObject.isEmpty())
        return;

    QJsonValue timeJsonValue = jsonObject.value("time");
    long timeT = timeJsonValue.toInt();
    dateTime.setTime_t(timeT);
}

void MainWindow::displaytime_init()
{
    /*get network time*/
//    QString url = "http://192.168.17.2:8080/time";
//    Http *http = new Http(url, Http::GET);
//    connect(http->getAccessManager(), &QNetworkAccessManager::finished,
//            this, &MainWindow::displaytime_getNetworkTimeCallback);
//    http->send();

    dateTime = QDateTime::currentDateTime();
    displaytime_timer = new QTimer();
    connect(displaytime_timer, &QTimer::timeout,
            this, &MainWindow::displaytime_timer_timeout);
    displaytime_timer->start(1000);
}

void MainWindow::displaytime_timer_timeout()
{
    int timeT = dateTime.toTime_t();
    dateTime.setTime_t(++timeT);
    displaytime_update_display(dateTime);
}

void MainWindow::displaytime_update_display(QDateTime dateTime)
{
    dateTime.setTime_t(dateTime.toTime_t() + 28800);
    QString cur_time_string = dateTime.toString("日期\nyyyy-MM-dd\n\n时间\nhh:mm:ss");
    ui->label_time->setText(cur_time_string);
}
